`include "common_header.verilog"

//  *************************************************************************
//  File : register_map_xgxs.v
//  *************************************************************************
//  This program is controlled by a written license agreement.
//  Unauthorized Reproduction or Use is Expressly Prohibited. 
//  Copyright (c) 2008 MoreThanIP.com, Germany
//  Designed by : Muhammad Anisur Rahman
//  info@morethanip.com
//  *************************************************************************
//  Decription : Registers for XGXS PCS
//  Version    : $Id: register_map_xgxs.v,v 1.9 2013/02/12 11:39:54 mr Exp $
//  *************************************************************************

module register_map_xgxs (
   reset_rx_clk,
   reset_tx_clk,
   reset_sd0_rx_clk,
   reset_sd1_rx_clk,
   reset_sd2_rx_clk,
   reset_sd3_rx_clk,
   reset_reg_clk,
   reg_clk,
   rx_clk,
   tx_clk,
   sd0_rx_clk,
   sd1_rx_clk,
   sd2_rx_clk,
   sd3_rx_clk,
   tx_err,
   sd_signal0,
   sd_signal1,
   sd_signal2,
   sd_signal3,
   ext_control,
   link_status,
   align_done,
   sync,
   cg_align,
   char_err,
   disp_err,
   comma_detect,
   match_fault,
   jumbo_en,
   reg_rd,
   reg_wr,
   reg_addr,
   reg_din,
   reg_dout,
   reg_busy,
   sw_reset
`ifdef MTIPXGXS_EEE_ENA          
   ,
   tx_lpi_active,
   rx_lpi_active
`endif
   
   );

`include "mtip_xgxs_package.verilog" 		

input   reset_rx_clk;           //  Asynchronous Reset
input   reset_tx_clk; 
input   reset_sd0_rx_clk;       //  Asynchronous Reset - sd0_rx_clk Domain
input   reset_sd1_rx_clk;       //  Asynchronous Reset - sd1_rx_clk Domain
input   reset_sd2_rx_clk;       //  Asynchronous Reset - sd2_rx_clk Domain
input   reset_sd3_rx_clk;       //  Asynchronous Reset - sd3_rx_clk Domain
input   reset_reg_clk;          //  Asynchronous Reset - reg_clk Domain        
input   reg_clk;                //  ReferenceInterface Clock
input   rx_clk;                 //  125MHz TBI Line Clock
input   tx_clk;                 //  125MHz Transmit GMII Clock
input   sd0_rx_clk;             //  SERDES Lane 0 Clock
input   sd1_rx_clk;             //  SERDES Lane 1 Clock
input   sd2_rx_clk;             //  SERDES Lane 2 Clock
input   sd3_rx_clk;             //  SERDES Lane 3 Clock
input   tx_err;                 //  Error on transmit path
input   sd_signal0;             //  SERDES Lane 0 Status        
input   sd_signal1;             //  SERDES Lane 1 Status        
input   sd_signal2;             //  SERDES Lane 2 Status        
input   sd_signal3;             //  SERDES Lane 3 Status
output  [1:0] ext_control;	//  EXTENTED vendor specific control (Keep unconnected if not used)
input   link_status;            //  Link status on receive path
input   align_done;             //  Alignment done
input   [3:0] sync;             //  Synchronization done
input   [3:0] cg_align;         //  Code group alignment done    
input   [3:0] char_err;         //  Character error detected   
input   [3:0] disp_err;         //  Disparity error detected 
input   [3:0] comma_detect;     //  Comma detect
input   match_fault;            //  Rate matching fault
input   jumbo_en;               //  Jumbo frame enable
input   reg_rd;                 //  Register Read Strobe
input   reg_wr;                 //  Register Write Strobe
input   [15:0] reg_addr;        //  Register Address
input   [15:0] reg_din;         //  Write Data for Host Bus
output   [15:0] reg_dout;       //  Read Data to Host Bus   
output   reg_busy;              //  Acknowledgement for read/ write operation  
output   sw_reset; 
`ifdef MTIPXGXS_EEE_ENA
input   tx_lpi_active;          // Indication from PCS TX STM that it is in LPI state.
input   rx_lpi_active;          // Indication from PCS RX STM that it is in LPI state.   
`endif

wire    [1:0] ext_control;
reg     [15:0] reg_dout;   
reg     reg_busy; 
wire    sw_reset; 

// TYPE stm_type:
parameter STM_TYPE_IDLE         = 3'd 0;
parameter STM_TYPE_READ         = 3'd 1;
parameter STM_TYPE_WRITE        = 3'd 2;
parameter STM_TYPE_WAIT_CYCLE   = 3'd 3;
parameter STM_TYPE_WAIT1        = 3'd 4;
parameter STM_TYPE_WAIT2        = 3'd 5;

reg     [2:0] state; 
reg     [2:0] nextstate; 

//  STATUS1 signals
//  ---------------
wire    clear_stat1; 

reg     link_status_reg1;
reg     link_status_reg2;

reg     [3:0] sd_signal_reg1;
reg     [3:0] sd_signal_reg2;


`ifdef MTIPXGXS_EEE_ENA
wire    tx_lpi_active_reg_clk;          // sync'ed to reg_clk
wire    rx_lpi_active_reg_clk;          // sync'ed to reg_clk
reg     pcs_status1_10;                 //  45.2.4.2 RX LPI, LH
reg     pcs_status1_11;                 //  45.2.4.2 TX LPI, LH
`endif

//  STATUS2 signals
//  ---------------
wire    c_rx_err; 
wire    c_tx_err; 
reg     clear_stat2; 
wire    capable_10gbase_w; 
wire    capable_10gbase_x; 
wire    capable_10gbase_r; 
wire    [15:0] status2; 

//  10GBASE-X PCS signals
//  ---------------------
wire    pat_test_ability; 
reg     align_done_reg1; 
reg     [3:0] sync_reg1; 
reg     align_done_reg2; 
reg     [3:0] sync_reg2; 
reg     [15:0] status_10gbase_x; 

//  CONTROL1 signals
//  ---------------
wire    [4:0] speed_select; 
wire    power_dwn; 
wire    speed_select1; 
wire    [15:0] control1; 
reg     control1_15_reg1; 
reg     control1_15_reg2; 
reg     control1_15_reg3; 
reg     control1_15_reg4; 
reg     sw_reset_int;

//  SCRATCH register
//  -------------                          
reg     [15:0] scratch_reg; 

//  EXTENTED STATUS REGISTER1
//  --------------------------  
reg     clear_ext_stat1; 
wire    [3:0] c_comma_detect; 
reg     [15:0] ext_status1; 
reg     [3:0] cg_align_d1; 
reg     [3:0] cg_align_d2; 
wire    [3:0] c_char_err; 
wire    [3:0] c_disp_err; 

//  EXTENTED STATUS REGISTER2
//  --------------------------
wire    c_match_fault; 
reg     clear_ext_stat2; 
wire    [15:0] ext_status2; 
wire    [15:1] ext_status2_15_1;
reg     ext_status2_0;
reg     jumbo_en_d1; 
reg     jumbo_en_d2; 

//  EXTENTED CONTROL REGISTER
//  -------------------------
reg    [1:0] ext_control_int;


//   Core design revision. 
//   --------------------                 
wire    [15:0] core_rev_w; 

//   PHY identifier
//   --------------                
wire    [31:0] phy_identifier_w; 

//   PACKAGE identifier
//   ------------------
wire    [31:0] pack_identifier_w; 
wire    [15:0] speed_ability; 
wire    [31:0] devices; 
wire    [15:0] control2; 
reg     reg_rd_int_reg; 
reg     reg_wr_int; 
reg     reg_rd_int; 
reg     [11:0] reg_sel; 
reg     reg_sel_vendor;         //  vendor defined addess space

reg     c_rx_err_stor;
reg     c_tx_err_stor;
reg     status1_link_stor;

always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_9
   if (reset_reg_clk == 1'b 1)
      begin
      reg_rd_int_reg <= 1'b 0;	
      end
   else
      begin
      reg_rd_int_reg <= reg_rd_int;	
      end
   end

//  CONTROL1 register
//  -----------------
always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_1a
   if (reset_reg_clk == 1'b 1)
      begin
      control1_15_reg3 <= 1'b 0;	
      control1_15_reg4 <= 1'b 0;	
      sw_reset_int <= 1'b 0;	
      end
   else
      begin
      control1_15_reg3 <= control1_15_reg2;	
      control1_15_reg4 <= control1_15_reg3;	

      //   Self-clearing software reset
      // 
      if (control1_15_reg4 == 1'b 1)
         begin
         sw_reset_int <= 1'b 0;	
         end
      else if (reg_wr_int == 1'b 1 & reg_sel == 12'h 000 & reg_sel_vendor == 1'b 0 )
         begin
         sw_reset_int <= reg_din[15];	
         end
      end
   end

//  Sofware reset domain crossing
// 
always @(posedge reset_rx_clk or posedge rx_clk)
   begin : process_1b
   if (reset_rx_clk == 1'b 1)
      begin
      control1_15_reg1 <= 1'b 0;	
      control1_15_reg2 <= 1'b 0;	
      end
   else
      begin
      control1_15_reg1 <= sw_reset_int;	
      control1_15_reg2 <= control1_15_reg1;	
      end
   end

//  STATUS1
//  -----------------------------------
assign clear_stat1 = (reg_rd_int == 1'b 0 & reg_rd_int_reg == 1'b 1 & reg_sel == 12'h 001 & reg_sel_vendor == 1'b 0) ? 1'b 1 : 1'b 0;

//  latch low for link status
always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_12
   if (reset_reg_clk == 1'b 1)
      begin
        status1_link_stor <= 1'b 1;	//  Link Status
        link_status_reg1  <= 1'b 0;
        link_status_reg2  <= 1'b 0;
      end
   else
      begin
        
        link_status_reg1 <= link_status;
        link_status_reg2 <= link_status_reg1;
        
      if (clear_stat1 == 1'b 1)
         begin
         status1_link_stor <= link_status_reg2;	//  reset on read
         end
      else if (link_status_reg2 == 1'b 0)       // latch low
         begin
         status1_link_stor <= 1'b 0;	
         end
      end
   end


// CDC for signal detect
always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_12b
   if (reset_reg_clk == 1'b 1)
      begin
      sd_signal_reg1  	<= 4'b 0000;
      sd_signal_reg2	<= 4'b 0000;
      end
   else
      begin
      sd_signal_reg1  	<= {sd_signal3, sd_signal2, sd_signal1, sd_signal0};
      sd_signal_reg2	<= sd_signal_reg1;      
      end
   end


`ifdef MTIPXGXS_EEE_ENA

mtip_xsync #(2) U_LPISY (
        
   .data_in({tx_lpi_active, rx_lpi_active}), 
   .reset(reset_reg_clk),  
   .clk(reg_clk), 
   .data_s({tx_lpi_active_reg_clk, rx_lpi_active_reg_clk}));      

always @(posedge reset_reg_clk or posedge reg_clk)
   begin:pst1_eee
   if (reset_reg_clk == 1'b 1)
      begin
      pcs_status1_10 <= 1'b 0;	
      pcs_status1_11 <= 1'b 0;	
      end
   else
      begin

        // 10: RX LPI, LatchHi
                
      if (rx_lpi_active_reg_clk==1'b1)
         begin
         pcs_status1_10 <= 1'b 1;
         end	
      else if (clear_stat1==1'b1) 
         begin
         pcs_status1_10 <= 1'b 0;
         end

        // 11: TX LPI, LatchHi
                
      if (tx_lpi_active_reg_clk==1'b1)
         begin
         pcs_status1_11 <= 1'b 1;
         end	
      else if (clear_stat1==1'b1) 
         begin
         pcs_status1_11 <= 1'b 0;
         end

      end
   end

`endif

//  STATUS2
//  --------------------
always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_13
   if (reset_reg_clk == 1'b 1)
      begin
      clear_stat2 <= 1'b 0;	
      end
   else
      begin
      if (reg_rd_int == 1'b 0 & reg_rd_int_reg == 1'b 1 & reg_sel == 12'h 008 & reg_sel_vendor == 1'b 0)
         begin
         clear_stat2 <= 1'b 1;	
         end
      else
         begin
         clear_stat2 <= 1'b 0;	
         end
      end
   end

assign c_rx_err = sd_signal_reg2 != 4'b 1111 |
	        (c_disp_err != 4'b 0000 | c_char_err != 4'b 0000 ) ? 1'b 1 : 1'b 0;


redge_ckxing u_tx_err (
          .reset(reset_tx_clk),
          .clk(tx_clk),
          .sig(tx_err),         //  input pulse
          .reset_clk_o(reset_reg_clk),
          .clk_o(reg_clk),
          .sig_o(c_tx_err));


always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_14a
   if (reset_reg_clk == 1'b 1)
      begin
      c_rx_err_stor <= 1'b 0;	//  transmit error & receive error
      end
   else
      begin
      if (clear_stat2 == 1'b 1)
         begin
         c_rx_err_stor <= 1'b 0;	//  reset on read
         end
`ifdef MTIPXGXS_EEE_ENA
      else if(c_rx_err == 1'b 1 & rx_lpi_active_reg_clk == 1'b 0)       // ignore errors while in low power
`else
      else if(c_rx_err == 1'b 1)
`endif
         begin
         c_rx_err_stor <= 1'b 1;	
         end     
      end
   end

always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_14b
   if (reset_reg_clk == 1'b 1)
      begin
      c_tx_err_stor <= 1'b 0;	//  transmit error & receive error
      end
   else
      begin
      if (clear_stat2 == 1'b 1)
         begin
         c_tx_err_stor <= 1'b 0;	//  reset on read
         end
`ifdef MTIPXGXS_EEE_ENA
      else if(c_tx_err == 1'b 1 & tx_lpi_active_reg_clk == 1'b 0)       // ignore errors while in low power
`else
      else if(c_tx_err == 1'b 1)
`endif
         begin
         c_tx_err_stor <= 1'b 1;
         end      
      end
   end

assign capable_10gbase_w = 1'b 0; 
assign capable_10gbase_x = 1'b 1; 
assign capable_10gbase_r = 1'b 0; 

assign status2[15:0] = { 4'b 1000, //  device responding
                         c_tx_err_stor, c_rx_err_stor, 7'b 0000000, capable_10gbase_w, capable_10gbase_x, capable_10gbase_r}; 



//  STATUS 10GBASE-X PCS
//  --------------------
assign pat_test_ability = 1'b 0; 
always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_15
   if (reset_reg_clk == 1'b 1)
      begin
      align_done_reg1 <= 1'b 0;	
      align_done_reg2 <= 1'b 0;	
      sync_reg1 <= 4'b 0000;	
      sync_reg2 <= 4'b 0000;	
      end
   else
      begin
      align_done_reg1 <= align_done;	
      align_done_reg2 <= align_done_reg1;	
      sync_reg1 <= sync;	
      sync_reg2 <= sync_reg1;	
      end
   end

always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_16
   if (reset_reg_clk == 1'b 1)
      begin
      status_10gbase_x[15:0] <= {5'b 00000, 1'b 0, 2'b 00, 8'h 00};	
      end
   else
      begin
      status_10gbase_x[15:13] <= {3{1'b 0}};	//  reserved 
      status_10gbase_x[12] <= align_done_reg2;	
      status_10gbase_x[11] <= pat_test_ability;	
      status_10gbase_x[10:4] <= {7{1'b 0}};	//  reserved
      status_10gbase_x[3:0] <= sync_reg2;	
      end
   end

assign speed_select[4:0]= 5'b 10000;    //  10Gbps
assign power_dwn        = 1'b 0; 
assign speed_select1    = 1'b 1;        //  10Gbps and above
assign control1[15:0]   = {sw_reset_int, 1'b 0, speed_select1, 1'b 0, 
                           power_dwn, 4'b 0000, speed_select, 2'b 00}; 

//  Software reset
//  -------------

assign sw_reset = control1[15];

//  ------------------ --
//  Extended Registers --
//  ------------------ -- 
//  Scratch Register
//  ----------------
always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_19
   if (reset_reg_clk == 1'b 1)
      begin
      scratch_reg <= {16{1'b 0}};	
      end
   else
      begin
      if (reg_sel_vendor == 1'b 1 & reg_sel == 12'h 000 & reg_wr_int == 1'b 1)
         begin
         scratch_reg <= reg_din;	
         end
      end
   end

// Vendor specific control
always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_19b
   if (reset_reg_clk == 1'b 1)
      begin
      ext_control_int <= {2{1'b 0}};	
      end
   else
      begin
      if (reg_sel_vendor == 1'b 1 & reg_sel == 12'h 004 & reg_wr_int == 1'b 1)
         begin
         ext_control_int <= reg_din[1:0];
         end
      end
   end

assign ext_control = ext_control_int;


//  EXTENTED STATUS REGISTER1
//  --------------------------  
always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_20
   if (reset_reg_clk == 1'b 1)
      begin
      clear_ext_stat1 <= 1'b 0;	
      end
   else
      begin
      if (reg_rd_int == 1'b 0 & reg_rd_int_reg == 1'b 1 & reg_sel == 12'h 002 & reg_sel_vendor == 1'b 1)
         begin
         clear_ext_stat1 <= 1'b 1;	
         end
      else
         begin
         clear_ext_stat1 <= 1'b 0;	
         end
      end
   end


redge_ckxing u_com0 (
          .reset(reset_sd0_rx_clk),
          .clk(sd0_rx_clk),
          .sig(comma_detect[0]), //  input pulse
          .reset_clk_o(reset_reg_clk),
          .clk_o(reg_clk),
          .sig_o(c_comma_detect[0]));

redge_ckxing u_com1 (
          .reset(reset_sd1_rx_clk),
          .clk(sd1_rx_clk),
          .sig(comma_detect[1]), //  input pulse
          .reset_clk_o(reset_reg_clk),
          .clk_o(reg_clk),
          .sig_o(c_comma_detect[1]));

redge_ckxing u_com2 (
          .reset(reset_sd2_rx_clk),
          .clk(sd2_rx_clk),
          .sig(comma_detect[2]), //  input pulse
          .reset_clk_o(reset_reg_clk),
          .clk_o(reg_clk),
          .sig_o(c_comma_detect[2]));

redge_ckxing u_com3 (
          .reset(reset_sd3_rx_clk),
          .clk(sd3_rx_clk),
          .sig(comma_detect[3]), //  input pulse
          .reset_clk_o(reset_reg_clk),
          .clk_o(reg_clk),
          .sig_o(c_comma_detect[3]));

always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_21
   if (reset_reg_clk == 1'b 1)
      begin
      ext_status1[3:0] <= {4{1'b 0}};	//  comma_detect for lane0 in reg clock domain     
      end
   else
      begin
      if (clear_ext_stat1 == 1'b 1)
         begin
         ext_status1[3:0] <= {4{1'b 0}};	//  reset on read
         end
      else
         begin
         if (c_comma_detect[0] == 1'b 1)
            begin
            ext_status1[0] <= 1'b 1;	
            end
         if (c_comma_detect[1] == 1'b 1)
            begin
            ext_status1[1] <= 1'b 1;	
            end
         if (c_comma_detect[2] == 1'b 1)
            begin
            ext_status1[2] <= 1'b 1;	
            end
         if (c_comma_detect[3] == 1'b 1)
            begin
            ext_status1[3] <= 1'b 1;	
            end
         end
      end
   end

always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_22
   if (reset_reg_clk == 1'b 1)
      begin
      cg_align_d1 <= {4{1'b 0}};	//  code group alignment done
      cg_align_d2 <= {4{1'b 0}};	
      end
   else
      begin
      cg_align_d1 <= cg_align;	
      cg_align_d2 <= cg_align_d1;	
      end
   end

always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_23
   if (reset_reg_clk == 1'b 1)
      begin
      ext_status1[7:4] <= {4{1'b 0}};	//  code group alignment done
      end
   else
      begin
      ext_status1[7:4] <= cg_align_d2;	
      end
   end


redge_ckxing u_ch_err0 (
          .reset(reset_sd0_rx_clk),
          .clk(sd0_rx_clk),
          .sig(char_err[0]),    //  input pulse
          .reset_clk_o(reset_reg_clk),
          .clk_o(reg_clk),
          .sig_o(c_char_err[0]));

redge_ckxing u_ch_err1 (
          .reset(reset_sd1_rx_clk),
          .clk(sd1_rx_clk),
          .sig(char_err[1]),    //  input pulse
          .reset_clk_o(reset_reg_clk),
          .clk_o(reg_clk),
          .sig_o(c_char_err[1]));

redge_ckxing u_ch_err2 (
          .reset(reset_sd2_rx_clk),
          .clk(sd2_rx_clk),
          .sig(char_err[2]),    //  input pulse
          .reset_clk_o(reset_reg_clk),
          .clk_o(reg_clk),
          .sig_o(c_char_err[2]));

redge_ckxing u_ch_err3 (
          .reset(reset_sd3_rx_clk),
          .clk(sd3_rx_clk),
          .sig(char_err[3]),    //  input pulse
          .reset_clk_o(reset_reg_clk),
          .clk_o(reg_clk),
          .sig_o(c_char_err[3]));

always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_24
   if (reset_reg_clk == 1'b 1)
      begin
      ext_status1[11:8] <= {4{1'b 0}};	//  character error for lane0 in reg clock domain     
      end
   else
      begin
      if (clear_ext_stat1 == 1'b 1)
         begin
         ext_status1[11:8] <= {4{1'b 0}};	//  reset on read
         end
      else
         begin
         if (c_char_err[0] == 1'b 1)
            begin
            ext_status1[8] <= 1'b 1;	
            end
         if (c_char_err[1] == 1'b 1)
            begin
            ext_status1[9] <= 1'b 1;	
            end
         if (c_char_err[2] == 1'b 1)
            begin
            ext_status1[10] <= 1'b 1;	
            end
         if (c_char_err[3] == 1'b 1)
            begin
            ext_status1[11] <= 1'b 1;	
            end
         end
      end
   end



redge_ckxing u_dsp_err0 (
          .reset(reset_sd0_rx_clk),
          .clk(sd0_rx_clk),
          .sig(disp_err[0]),    //  input pulse
          .reset_clk_o(reset_reg_clk),
          .clk_o(reg_clk),
          .sig_o(c_disp_err[0]));

redge_ckxing u_dsp_err1 (
          .reset(reset_sd1_rx_clk),
          .clk(sd1_rx_clk),
          .sig(disp_err[1]),    //  input pulse
          .reset_clk_o(reset_reg_clk),
          .clk_o(reg_clk),
          .sig_o(c_disp_err[1]));

redge_ckxing u_dsp_err2 (
          .reset(reset_sd2_rx_clk),
          .clk(sd2_rx_clk),
          .sig(disp_err[2]),    //  input pulse
          .reset_clk_o(reset_reg_clk),
          .clk_o(reg_clk),
          .sig_o(c_disp_err[2]));

redge_ckxing u_dsp_err3 (
          .reset(reset_sd3_rx_clk),
          .clk(sd3_rx_clk),
          .sig(disp_err[3]),    //  input pulse
          .reset_clk_o(reset_reg_clk),
          .clk_o(reg_clk),
          .sig_o(c_disp_err[3]));

always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_25
   if (reset_reg_clk == 1'b 1)
      begin
      ext_status1[15:12] <= {4{1'b 0}};	//  disparity error for lane0 in reg clock domain     
      end
   else
      begin
      if (clear_ext_stat1 == 1'b 1)
         begin
         ext_status1[15:12] <= {4{1'b 0}};	//  reset on read
         end
      else
         begin
         if (c_disp_err[0] == 1'b 1)
            begin
            ext_status1[12] <= 1'b 1;	
            end
         if (c_disp_err[1] == 1'b 1)
            begin
            ext_status1[13] <= 1'b 1;	
            end
         if (c_disp_err[2] == 1'b 1)
            begin
            ext_status1[14] <= 1'b 1;	
            end
         if (c_disp_err[3] == 1'b 1)
            begin
            ext_status1[15] <= 1'b 1;	
            end
         end
      end
   end

//  EXTENTED STATUS REGISTER2
//  --------------------------
always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_26
   if (reset_reg_clk == 1'b 1)
      begin
      clear_ext_stat2 <= 1'b 0;	
      end
   else
      begin
      if (reg_rd_int == 1'b 0 & reg_rd_int_reg == 1'b 1 & reg_sel == 12'h 003 & reg_sel_vendor == 1'b 1)
         begin
         clear_ext_stat2 <= 1'b 1;	
         end
      else
         begin
         clear_ext_stat2 <= 1'b 0;	
         end
      end
   end

redge_ckxing u_match_flt (
          .reset(reset_rx_clk),
          .clk(rx_clk),
          .sig(match_fault),    //  input pulse
          .reset_clk_o(reset_reg_clk),
          .clk_o(reg_clk),
          .sig_o(c_match_fault));

always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_27
   if (reset_reg_clk == 1'b 1)
      begin
      ext_status2_0 <= 1'b 0;	//  rate matching fault in reg clock domain                      
      end
   else
      begin
      if (clear_ext_stat2 == 1'b 1)
         begin
         ext_status2_0 <= 1'b 0;	//  reset on read
         end
      else if (c_match_fault == 1'b 1 & clear_ext_stat2 == 1'b 0 )
         begin
         ext_status2_0 <= 1'b 1;	
         end
      end
   end

always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_28
   if (reset_reg_clk == 1'b 1)
      begin
      jumbo_en_d1 <= 1'b 0;	//  Jumbo frame enable
      jumbo_en_d2 <= 1'b 0;	//  Jumbo frame enable
      end
   else
      begin
      jumbo_en_d1 <= jumbo_en;	
      jumbo_en_d2 <= jumbo_en_d1;	
      end
   end

assign ext_status2_15_1 = {12'h 000, 2'b 00, jumbo_en_d2}; 

assign ext_status2[15:1] = ext_status2_15_1;
assign ext_status2[0]    = ext_status2_0;

//   Core design revision. 
//   --------------------         
assign core_rev_w = MTIPXGXS_DEV_VERSION; 

//   PHY identifier
//   --------------                
assign phy_identifier_w = MTIPXGXS_PHY_IDENTIFIER; 

//   PACKAGE identifier
//   ------------------
assign pack_identifier_w = MTIPXGXS_PACK_IDENTIFIER; 


assign speed_ability    = 16'h 0001;                    //  PCS is capable of 10Gbps        
assign devices          = {28'h 0000000, 4'b 1000};     //  check and verify (PCS is present in the package)        
assign control2         = {12'h 000, 2'b 00, 2'b 01};   // 10GBASE-X PCS

//  Read MUX
//  --------
always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_29
   if (reset_reg_clk == 1'b 1)
      begin
      reg_dout <= {16{1'b 0}};	
      end
   else
      begin
      if (reg_rd_int == 1'b 1)
         begin
         if (reg_sel_vendor == 1'b 1)
            begin
            case (reg_sel)
            12'h 000:
               begin
               reg_dout <= scratch_reg;	
               end
            12'h 001:
               begin
               reg_dout <= core_rev_w;	
               end
            12'h 002:
               begin
               reg_dout <= ext_status1;	
               end
            12'h 003:
               begin
               reg_dout <= ext_status2;	
               end
            12'h 004:
               begin
               reg_dout <= {14'd 0, ext_control_int};	
               end            
            default:
               begin
               reg_dout <= {16{1'b 0}};	
               end
            endcase
            end
         else
            begin
            case (reg_sel)
            12'h 000:
               begin
               reg_dout <= control1;
               end
            12'h 001:   // STATUS1 (4.1)
               begin
               reg_dout[0] <= 1'b 0;            // reserved	
               reg_dout[1] <= 1'b 0;	        // low power mode support (not EEE)
               reg_dout[2] <= status1_link_stor;// link status, LL
               reg_dout[3] <= 1'b 0;	
               reg_dout[4] <= 1'b 0;	
               reg_dout[5] <= 1'b 0;	
               reg_dout[6] <= 1'b 0;	
               reg_dout[7] <= c_rx_err_stor | c_tx_err_stor; // LH from STATUS2 bits 10,11

               `ifdef MTIPXGXS_EEE_ENA

               reg_dout[8]    <= rx_lpi_active_reg_clk;                     // real time indication
               reg_dout[9]    <= tx_lpi_active_reg_clk;                     // real time indication
               reg_dout[10]   <= pcs_status1_10;                            // LatchHi
               reg_dout[11]   <= pcs_status1_11;                            // LatchHi
               reg_dout[15:12] <= 4'd0;                                      //  Reserved

               `else

               reg_dout[15:8] <= 8'd0;                                      //  Reserved

               `endif
               
               end
            12'h 002:
               begin
               reg_dout <= phy_identifier_w[15:0];	
               end
            12'h 003:
               begin
               reg_dout <= phy_identifier_w[31:16];	
               end
            12'h 004:
               begin
               reg_dout <= speed_ability;	
               end
            12'h 005:
               begin
               reg_dout <= devices[15:0];	
               end
            12'h 006:
               begin
               reg_dout <= devices[31:16];	
               end
            12'h 007:
               begin
               reg_dout <= control2;	
               end
            12'h 008:
               begin
               reg_dout <= status2;	
               end
            12'h 00E:
               begin
               reg_dout <= pack_identifier_w[15:0];	
               end
            12'h 00F:
               begin
               reg_dout <= pack_identifier_w[31:16];	
               end
            12'h 018:
               begin
               reg_dout <= status_10gbase_x;	
               end
            default:
               begin
               reg_dout <= {16{1'b 0}};	
               end
            endcase
            end
         end
      else
         begin
         reg_dout <= {16{1'b 0}};	
         end
      end
   end

//  STM
//  ---
always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_30
   if (reset_reg_clk == 1'b 1)
      begin
      state <= STM_TYPE_IDLE;	
      end
   else
      begin
      state <= nextstate;	
      end
   end

always @(state or reg_rd or reg_wr)
   begin : process_31
   case (state)
   STM_TYPE_IDLE:
      begin

//  Write Accesses
//  --------------------
      if (reg_wr == 1'b 1)
         begin
         nextstate = STM_TYPE_WRITE;	

//  Read Accesses
//  -------------------
         end
      else if (reg_rd == 1'b 1 )
         begin
         nextstate = STM_TYPE_READ;	
         end
      else
         begin
         nextstate = STM_TYPE_IDLE;	
         end
      end
   STM_TYPE_READ:
      begin
      nextstate = STM_TYPE_WAIT_CYCLE;	//  cyc_done will be 0. Used as 1 delay here    
      end
   STM_TYPE_WRITE:
      begin
      nextstate = STM_TYPE_WAIT_CYCLE;	//  cyc_done will be 0. Used as 1 delay here

// when NEXT_CYCLE =>                        
// nextstate = WAIT_CYCLE ;
      end
   STM_TYPE_WAIT_CYCLE:
      begin
//  acknowledge                                                                
      nextstate = STM_TYPE_WAIT1;	
      end
   STM_TYPE_WAIT1:
      begin
//  extra latency for input registers
      nextstate = STM_TYPE_WAIT2;	
      end
   STM_TYPE_WAIT2:
      begin
//  extra latency for output registers
      nextstate = STM_TYPE_IDLE;	
      end
   default:
      begin
      nextstate = STM_TYPE_IDLE;	
      end
   endcase
   end

//  Registers Control
//  -----------------                                        
always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_32
   if (reset_reg_clk == 1'b 1)
      begin
      reg_wr_int <= 1'b 0;	
      reg_rd_int <= 1'b 0;	
      end
   else
      begin
//  read pulse
      if (nextstate == STM_TYPE_READ)
         begin
         reg_rd_int <= 1'b 1;	
         end
      else
         begin
         reg_rd_int <= 1'b 0;	
         end
//  write pulse
      if (nextstate == STM_TYPE_WRITE)
         begin
         reg_wr_int <= 1'b 1;	//  wr_reg
         end
      else
         begin
         reg_wr_int <= 1'b 0;	
         end
      end
   end

always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_33
   if (reset_reg_clk == 1'b 1)
      begin
      reg_sel <= {12{1'b 0}};	
      end
   else
      begin
      reg_sel <= reg_addr[11:0];	
      end
   end

always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_34
   if (reset_reg_clk == 1'b 1)
      begin
      reg_sel_vendor <= 1'b 0;	
      end
   else
      begin
      if (reg_addr[15:12] >= 4'h 8)
         begin
         reg_sel_vendor <= 1'b 1;	
         end
      else
         begin
         reg_sel_vendor <= 1'b 0;	
         end
      end
   end

always @(posedge reset_reg_clk or posedge reg_clk)
   begin : process_35
   if (reset_reg_clk == 1'b 1)
      begin
      reg_busy <= 1'b 1;	
      end
   else
      begin
      if (nextstate == STM_TYPE_WAIT_CYCLE)
         begin
         reg_busy <= 1'b 0;	
         end
      else
         begin
         reg_busy <= 1'b 1;	
         end
      end
   end


endmodule // module register_map_xgxs

